<script>
import YmFormField from './YmFormField'
import {NAME, WIDGET, LABEL} from "@/store/elementui"
import { COL, GROUP_FIELD, FIELDS, getDefaultValue } from "@/store/form"
import Util from '@/util'

/**
 * 绘制域
 * @param {field} field 域
 * @param {CreateElement} h vNode生成函数
 * @param {number} index 序号
 * @param {{}} obj value
 * @param {fields} props 参数
 * @param {{}} listeners 事件处理器
 */
function renderField(field, index, h, obj, listeners, props) {
  let name = field[NAME] ? field[NAME] : undefined

  // 处理disable
  let disabled = Util.isDisabled(field, obj)
  if (disabled && name && obj[name] !== undefined) delete obj[name]

  if (field[WIDGET] === GROUP_FIELD) return renderGroup(field, index, h, obj, listeners)

  //
  let labelPosition = field.labelPosition || props.labelPosition


  const fnValue = (field) => {
    if (field[NAME] !== undefined && obj[field[NAME]] !== undefined) {
      return obj[field[NAME]]
    }
    return getDefaultValue(field)
  }

  let value = fnValue(field)

  let span = field[COL] || 24

  const setter = (name) => {
    return (v) => {
      if (name) {
        obj[name] = v
        listeners.input && listeners.input(obj)
      }
    }
  }

  const deleter = (name) => {
    return () => {
      if (name && obj[name] !== undefined) {
        delete obj[name]
        listeners.input && listeners.input(obj)
      }
    }
  }

  const onClick = listeners.click

  let vNode = h(YmFormField, {
    props: {
      ...field,
      value,
      disabled,
      labelPosition
    },
    on: {
      ...listeners,
      input: setter(name),
      change: setter(name),
      delete: deleter(name)
    }
  })

  return h('el-col', {
    props: {
      span
    },
    nativeOn: {
      click: () => {
        onClick && onClick(field, index)
      }
    }
  }, [vNode])
}

/**
 * 生成 group
 * @param {field} field 域
 * @param {CreateElement} h vNode生成函数
 * @param {number} index 序号
 * @param {{}} obj value
 * @param {{}} listeners 事件处理器
 */
function renderGroup(field, index, h, obj, listeners) {
  let name = field[NAME] ? field[NAME] : undefined
  const value = name !== undefined && obj[name] !== undefined ? obj[field[NAME]] : {}

  const on = {
    input: (v) => {
      if (!name) return
      const o = {
        ...obj,
        [name]: v
      }
      listeners.input && listeners.input(o)
    },
    change: (v) => {
      if (!name) return
      const o = {
        ...obj,
        [name]: v
      }
      listeners.change && listeners.change(o)
    }
  }

  return (
    <el-col span={24}>
      <el-row >
        <el-col span={24}>
          <el-divider content-position="left">{field[LABEL]}</el-divider>
        </el-col>
        <el-col span={24} class="ym-group-content">
          {renderFields(h,  value, field, on)}
        </el-col>
      </el-row>
    </el-col>
  )
}

/**
 * 生成一组表单域
 * @param {CreateElement} h vNode生成函数
 * @param {{}} obj value
 * @param {{}} props 参数
 * @param {{}} listeners 事件处理器
 */
function renderFields(h, obj, props, listeners) {
  const fields = props[FIELDS]
  if (!fields) {
    console.log('render fields error', props)
    return []
  }

  const vNodes = fields.map((field, index) => {
    return renderField(field, index, h, obj, listeners, props)
  })

  return h('el-row', {
    props: {
      gutter: 20
    }
  }, vNodes)
}

/**
 * props { fields: array<filed>, value }
 *   响应 delete 事件
 */
export default {
  name: 'YmFormFields',
  functional: true,
  render (h, context) {
    const { props, listeners } = context

    // 表单值对象
    const obj = {
      ...props.value
    }

    return renderFields(h, obj, props, listeners)
  }
}
</script>

<style>
.ym-group-content {
  margin-top: -24px;
  padding: 24px;
  border: 1px solid #DCDFE6;
  border-top: 0;
}
</style>
